#include <iostream>
#include <string>
#include <memory> // 使用智能指针，防止内存泄漏

// 1. 抽象组件：定义所有咖啡的基本行为接口
class Beverage {
public:
    virtual std::string getDescription() const = 0; // 获取描述
    virtual double cost() const = 0;                // 获取价格
    virtual ~Beverage() = default;                 // 虚析构函数，避免内存泄漏
};

// 2. 具体组件：基础咖啡（黑咖啡）
class BlackCoffee : public Beverage {
public:
    std::string getDescription() const override {
        return "黑咖啡";
    }

    double cost() const override {
        return 5.0; // 黑咖啡的基础价格
    }
};

// 3. 抽象装饰器：持有一个 `Beverage` 指针，用于扩展功能
class BeverageDecorator : public Beverage {
protected:
    std::shared_ptr<Beverage> beverage; // 持有被装饰的对象（组合）

public:
    explicit BeverageDecorator(std::shared_ptr<Beverage> b) : beverage(std::move(b)) {}
    virtual ~BeverageDecorator() = default;
};

// 4. 具体装饰器：实现动态功能扩展
// 4.1 牛奶装饰器
class MilkDecorator : public BeverageDecorator {
public:
    explicit MilkDecorator(std::shared_ptr<Beverage> b) : BeverageDecorator(std::move(b)) {}

    std::string getDescription() const override {
        return beverage->getDescription() + " + 牛奶"; // 在描述中添加牛奶
    }

    double cost() const override {
        return beverage->cost() + 1.0; // 增加牛奶价格
    }
};

// 4.2 糖装饰器
class SugarDecorator : public BeverageDecorator {
public:
    explicit SugarDecorator(std::shared_ptr<Beverage> b) : BeverageDecorator(std::move(b)) {}

    std::string getDescription() const override {
        return beverage->getDescription() + " + 糖"; // 在描述中添加糖
    }

    double cost() const override {
        return beverage->cost() + 0.5; // 增加糖价格
    }
};

// 4.3 巧克力装饰器
class ChocolateDecorator : public BeverageDecorator {
public:
    explicit ChocolateDecorator(std::shared_ptr<Beverage> b) : BeverageDecorator(std::move(b)) {}

    std::string getDescription() const override {
        return beverage->getDescription() + " + 巧克力"; // 在描述中添加巧克力
    }

    double cost() const override {
        return beverage->cost() + 2.0; // 增加巧克力价格
    }
};

// 5. 主函数：测试装饰器模式的功能
int main() {
    // 1. 创建基础的黑咖啡
    std::shared_ptr<Beverage> coffee = std::make_shared<BlackCoffee>();
    std::cout << "基础订单：" << coffee->getDescription() << "，价格：" << coffee->cost() << " 元" << std::endl;

    // 2. 动态添加装饰器功能
    coffee = std::make_shared<MilkDecorator>(coffee); // 添加牛奶
    std::cout << "加牛奶后：" << coffee->getDescription() << "，价格：" << coffee->cost() << " 元" << std::endl;

    coffee = std::make_shared<SugarDecorator>(coffee); // 添加糖
    std::cout << "加糖后：" << coffee->getDescription() << "，价格：" << coffee->cost() << " 元" << std::endl;

    coffee = std::make_shared<ChocolateDecorator>(coffee); // 添加巧克力
    std::cout << "加巧克力后：" << coffee->getDescription() << "，价格：" << coffee->cost() << " 元" << std::endl;

    return 0;
}
